using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using static WaterCylinder.Resource;

/*
武器类


关于伤害计算：
伤害计算只会发生在Bullet类与Entity类的碰撞中
HandWeapon负责接受Entity的输入，然后经过一系列调用调用到Weapon的Shot方法
Shot方法会发射预先在Weapon里存储的子弹，并设置子弹的伤害
设置子弹伤害取决于子弹本身的伤害值和发射子弹的Entity的attribute
attribute计算方法详见RPGValue类
*/

[CreateAssetMenu(menuName = "Item/Weapon")]
[Serializable]
public class Weapon : Item
{   
    public static new Weapon Create(ScriptableObject prefab){
        return Instantiate(prefab) as Weapon;
    }
    
    public static new Weapon Create(string path){
        return Create(GetResources<ScriptableObject>("Weapons/" + path));
    }
    

    /// <summary>
    /// 射击时间间隔
    /// </summary>
    public float shotTime;
    [Tooltip("Disable")]
    public float time;
    
    public HandWeapon handWeapon;
    public Bullet currentBullet;
    UnityAction<Weapon,int> bulletSetter;
    //给发射后添加子弹处理事件
    public void ShotSet(UnityAction<Bullet> set){
        if(bulletSetter != null)
            shotEvent.RemoveListener(bulletSetter);
        bulletSetter = (w,n)=>set.Invoke(currentBullet);
        shotEvent.AddListener(bulletSetter);
    }
    
    public List<GameObject> bullets = new List<GameObject>();
    
    [Tooltip("Event")]
    public WeaponEvent shotEvent;
    [Tooltip("Event")]
    public WeaponEvent  processEvent;
    
    /// <summary>
    /// 武器协程方法
    /// </summary>
    public virtual void OnProcess(){}
    
    //发射某个子弹
    public void Shot(int id){
        currentBullet = Bullet.CreatBullet(bullets[id], owner, null, handWeapon.transform.position);
        if(owner != null){
            //设置子弹伤害
            currentBullet.damage.value = owner.GetDamage(currentBullet.damage);
        }
    }
    
    public override void OnUse(Entity user, int arg = 0){
        base.OnUse(user, arg);
        if(time >= shotTime){
            shotEvent?.Invoke(this, arg);
            time = 0;
        }
    }

    public static float weaponProcessTime = 0.01f;
    
    public IEnumerator Process(){
        while(true){
            processEvent?.Invoke(this,0);
            OnProcess();
            time += weaponProcessTime;
            yield return new WaitForSeconds(weaponProcessTime);
        }
    }
    
    public override void Reset(){
        base.Reset();
        time = 0;
        bullets.Clear();
    }

}
